home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / a_utils / _archvrs / unix / arc521.lha / arc / marc.c < prev    next >
C/C++ Source or Header  |  1989-08-08  |  9KB  |  323 lines

  1. /*
  2.  * $Header: marc.c,v 1.5 88/08/01 14:19:19 hyc Exp $
  3.  */
  4.  
  5. /*  MARC - Archive merge utility
  6.  
  7.     Version 5.21, created on 04/22/87 at 15:05:10
  8.  
  9. (C) COPYRIGHT 1985-87 by System Enhancement Associates; ALL RIGHTS RESERVED
  10.  
  11.     By:     Thom Henderson
  12.  
  13.     Description:
  14.      This program is used to "merge" archives.  That is, to move
  15.      files from one archive to another with no data conversion.
  16.      Please refer to the ARC source for a description of archives
  17.      and archive formats.
  18.  
  19.     Instructions:
  20.      Run this program with no arguments for complete instructions.
  21.  
  22.     Language:
  23.      Computer Innovations Optimizing C86
  24. */
  25. #include <stdio.h>
  26. #include "arc.h"
  27.  
  28. #if    UNIX
  29. #include <sys/types.h>
  30. #include <sys/stat.h>
  31. #endif
  32.  
  33. FILE *src;                   /* source archive */
  34. char srcname[STRLEN];               /* source archive name */
  35.  
  36. static char **lst;               /* files list */
  37. static int lnum;               /* length of files list */
  38.  
  39.  
  40. main(nargs,arg)                   /* system entry point */
  41. int nargs;                   /* number of arguments */
  42. char *arg[];                   /* pointers to arguments */
  43. {
  44.     char *makefnam();               /* filename fixup routine */
  45.     char *calloc();               /* memory manager */
  46.     char *envfind();
  47. #if    !MTS
  48.     char *arctemp2, *mktemp();        /* temp file stuff */
  49. #endif
  50. #if    GEMDOS
  51.     void exitpause();
  52. #endif
  53.     int n;                   /* index */
  54. #if    UNIX
  55.     struct    stat    sbuf;
  56. #endif
  57.  
  58.  
  59.     if(nargs<3)
  60.     {     printf("MARC - Archive merger, Version 5.21, created on 04/22/87 at 15:05:10\n");
  61. /*     printf("(C) COPYRIGHT 1985,86,87 by System Enhancement Associates;");
  62.      printf(" ALL RIGHTS RESERVED\n\n");
  63.      printf("Please refer all inquiries to:\n\n");
  64.      printf("    System Enhancement Associates\n");
  65.      printf("    21 New Street, Wayne NJ 07470\n\n");
  66.      printf("You may copy and distribute this program freely,");
  67.      printf(" provided that:\n");
  68.      printf("    1)      No fee is charged for such copying and");
  69.      printf(" distribution, and\n");
  70.      printf("    2)      It is distributed ONLY in its original,");
  71.      printf(" unmodified state.\n\n");
  72.      printf("If you like this program, and find it of use, then your");
  73.      printf(" contribution will\n");
  74.      printf("be appreciated.  You may not use this product in a");
  75.      printf(" commercial environment\n");
  76.      printf("or a governmental organization without paying a license");
  77.      printf(" fee of $35.  Site\n");
  78.      printf("licenses and commercial distribution licenses are");
  79.      printf(" available.  A program\n");
  80.      printf("disk and printed documentation are available for $50.\n");
  81.      printf("\nIf you fail to abide by the terms of this license, ");
  82.      printf(" then your conscience\n");
  83.      printf("will haunt you for the rest of your life.\n\n");
  84. */
  85.      printf("Usage: MARC <tgtarc> <srcarc> [<filename> . . .]\n");
  86.      printf("Where: <tgtarc> is the archive to add files to,\n");
  87.      printf("    <srcarc> is the archive to get files from, and\n");
  88.      printf("    <filename> is zero or more file names to get.\n");
  89.      printf("\nAdapted from MSDOS by Howard Chu\n");
  90. #if    GEMDOS
  91.      exitpause();
  92. #endif
  93.      return 1;
  94.     }
  95.  
  96.     /* see where temp files go */
  97. #if    !MTS
  98.     arctemp = calloc(1, STRLEN);
  99.     if (!(arctemp2 = envfind("ARCTEMP")))
  100.         arctemp2 = envfind("TMPDIR");
  101.     if (arctemp2) {
  102.         strcpy(arctemp, arctemp2);
  103.         n = strlen(arctemp);
  104.         if (arctemp[n - 1] != CUTOFF)
  105.             arctemp[n] = CUTOFF;
  106.     }
  107. #if    UNIX
  108.     else    strcpy(arctemp, "/tmp/");
  109. #endif
  110. #if    !MSDOS
  111.     {
  112.         static char tempname[] = "AXXXXXX";
  113.         strcat(arctemp, mktemp(tempname));
  114.     }
  115. #else
  116.     strcat(arctemp, "$ARCTEMP");
  117. #endif
  118. #else
  119.     guinfo("SHFSEP    ", gotinf);
  120.     sepchr[0] = gotinf[0];
  121.     guinfo("SCRFCHAR", gotinf);
  122.     tmpchr[0] = gotinf[0];
  123.     arctemp = "-$$$";
  124.     arctemp[0] = tmpchr[0];
  125. #endif
  126.  
  127. #if    UNIX
  128.     if (!stat(arg[1],&sbuf))
  129.         strcpy(arcname,arg[1]);
  130.     else
  131.         makefnam(arg[1],".arc",arcname);
  132.     if (!stat(arg[2],&sbuf))
  133.         strcpy(srcname,arg[2]);
  134.     else
  135.         makefnam(arg[2],".arc",srcname);
  136. #else
  137.     makefnam(arg[1],".ARC",arcname);   /* fix up archive names */
  138.     makefnam(arg[2],".ARC",srcname);
  139. /*    makefnam(".$$$",arcname,newname);*/
  140.     sprintf(newname,"%s.arc",arctemp);
  141. #endif
  142.  
  143.     arc = fopen(arcname,OPEN_R);           /* open the archives */
  144.     if(!(src=fopen(srcname,OPEN_R)))
  145.      abort("Cannot read source archive %s",srcname);
  146.     if(!(new=fopen(newname,OPEN_W)))
  147.      abort("Cannot create new archive %s",newname);
  148.  
  149.     if(!arc)
  150.      printf("Creating new archive %s\n",arcname);
  151.  
  152.     /* get the files list set up */
  153.  
  154.     lnum = nargs-3;               /* initial length of list */
  155.     if(lnum<1)                   /* phoney for default case */
  156.     {     lnum = 1;
  157.      lst = (char **) calloc(1,sizeof(char *));
  158.      lst[0] = "*.*";
  159.     }
  160.     else                   /* else use filenames given */
  161.     {     lst = (char **) calloc(lnum,sizeof(char *));
  162.      for(n=3; n<nargs; n++)
  163.           lst[n-3] = arg[n];
  164.  
  165.      for(n=0; n<lnum; )           /* expand indirect references */
  166.      {    if(*lst[n] == '@')
  167.            expandlst(n);
  168.           else n++;
  169.      }
  170.     }
  171.  
  172.     merge(lnum,lst);               /* merge desired files */
  173.  
  174.     if(arc) fclose(arc);           /* close the archives */
  175.     fclose(src);
  176.     fclose(new);
  177.  
  178.     if(arc)                   /* make the switch */
  179.      if(unlink(arcname))
  180.           abort("Unable to delete old copy of %s",arcname);
  181.     if(move(newname,arcname))
  182.      abort("Unable to rename %s to %s",newname,arcname);
  183.  
  184.     setstamp(arcname,arcdate,arctime);     /* new arc matches newest file */
  185.  
  186. #if    GEMDOS
  187.     exitpause();
  188. #endif
  189.     return nerrs;
  190. }
  191.  
  192. merge(nargs,arg)               /* merge two archives */
  193. int nargs;                   /* number of filename templates */
  194. char *arg[];                   /* pointers to names */
  195. {
  196.     struct heads srch;               /* source archive header */
  197.     struct heads arch;               /* target archive header */
  198.     int gotsrc, gotarc;               /* archive entry versions (0=end) */
  199.     int copy;                   /* true to copy file from source */
  200.     int n;                   /* index */
  201.  
  202.     gotsrc = gethdr(src,&srch);           /* get first source file */
  203.     gotarc = gethdr(arc,&arch);           /* get first target file */
  204.  
  205.     while(gotsrc || gotarc)           /* while more to merge */
  206.     {     if(strcmp(srch.name,arch.name)>0)
  207.      {    copyfile(arc,&arch,gotarc);
  208.           gotarc = gethdr(arc,&arch);
  209.      }
  210.  
  211.      else if(strcmp(srch.name,arch.name)<0)
  212.      {    copy = 0;
  213.           for(n=0; n<nargs; n++)
  214.           {       if(match(srch.name,arg[n]))
  215.            {    copy = 1;
  216.             break;
  217.            }
  218.           }
  219.           if(copy)               /* select source or target */
  220.           {       printf("Adding file:      %s\n",srch.name);
  221.            copyfile(src,&srch,gotsrc);
  222.           }
  223.           else fseek(src,srch.size,1);
  224.           gotsrc = gethdr(src,&srch);
  225.      }
  226.  
  227.      else                   /* duplicate names */
  228.      {    copy = 0;
  229.           {       if((srch.date>arch.date)
  230.            || (srch.date==arch.date && srch.time>arch.time))
  231.            {    for(n=0; n<nargs; n++)
  232.             {    if(match(srch.name,arg[n]))
  233.                  {      copy = 1;
  234.                   break;
  235.                  }
  236.             }
  237.            }
  238.           }
  239.           if(copy)               /* select source or target */
  240.           {       printf("Updating file: %s\n",srch.name);
  241.            copyfile(src,&srch,gotsrc);
  242.            gotsrc = gethdr(src,&srch);
  243.            if(gotarc)
  244.            {    fseek(arc,arch.size,1);
  245.             gotarc = gethdr(arc,&arch);
  246.            }
  247.           }
  248.           else
  249.           {       copyfile(arc,&arch,gotarc);
  250.            gotarc = gethdr(arc,&arch);
  251.            if(gotsrc)
  252.            {    fseek(src,srch.size,1);
  253.             gotsrc = gethdr(src,&srch);
  254.            }
  255.           }
  256.      }
  257.     }
  258.  
  259.     hdrver = 0;                   /* end of archive marker */
  260.     writehdr(&arch,new);           /* mark the end of the archive */
  261. }
  262.  
  263. int gethdr(f,hdr)               /* special read header for merge */
  264. FILE *f;                   /* file to read from */
  265. struct heads *hdr;               /* storage for header */
  266. {
  267.     char *i = hdr->name;           /* string index */
  268.     int n;                   /* index */
  269.  
  270.     for(n=0; n<FNLEN; n++)           /* fill name field */
  271.      *i++ = 0176;               /* impossible high value */
  272.     *--i = '\0';               /* properly end the name */
  273.  
  274.     hdrver = 0;                   /* reset header version */
  275.     if(readhdr(hdr,f))               /* use normal reading logic */
  276.      return hdrver;               /* return the version */
  277.     else return 0;               /* or fake end of archive */
  278. }
  279.  
  280. copyfile(f,hdr,ver)               /* copy a file from an archive */
  281. FILE *f;                   /* archive to copy from */
  282. struct heads *hdr;               /* header data for file */
  283. int ver;                   /* header version */
  284. {
  285.     hdrver = ver;               /* set header version */
  286.     writehdr(hdr,new);               /* write out the header */
  287.     filecopy(f,new,hdr->size);           /* copy over the data */
  288. }
  289.  
  290. static expandlst(n)               /* expand an indirect reference */
  291. int n;                       /* number of entry to expand */
  292. {
  293.     FILE *lf, *fopen();               /* list file, opener */
  294.     char *malloc(), *realloc();           /* memory managers */
  295.     char buf[100];               /* input buffer */
  296.     int x;                   /* index */
  297.     char *p = lst[n]+1;               /* filename pointer */
  298.  
  299.     if(*p)                   /* use name if one was given */
  300.     {     makefnam(p,".CMD",buf);
  301.      upper(buf);
  302.      if(!(lf=fopen(buf,"r")))
  303.           abort("Cannot read list of files in %s",buf);
  304.     }
  305.     else lf = stdin;               /* else use standard input */
  306.  
  307.     for(x=n+1; x<lnum; x++)           /* drop reference from the list */
  308.      lst[x-1] = lst[x];
  309.     lnum--;
  310.  
  311.     while(fscanf(lf,"%99s",buf)>0)     /* read in the list */
  312.     {     if(!(lst=(char **) realloc(lst,(lnum+1)*sizeof(char *))))
  313.           abort("too many file references");
  314.  
  315.      lst[lnum] = malloc(strlen(buf)+1);
  316.      strcpy(lst[lnum],buf);           /* save the name */
  317.      lnum++;
  318.     }
  319.  
  320.     if(lf!=stdin)               /* avoid closing standard input */
  321.      fclose(lf);
  322. }
  323.